package org.hhf.core;

/**
 * StringRedis类实现了Redis的字符串数据类型操作
 */
public class StringRedis {
    private final RedisCore core;

    public StringRedis(RedisCore core) {
        this.core = core;
    }

    /**
     * 设置字符串值
     */
    public String set(String key, String value) {
        core.put(key, value, RedisCore.DataType.STRING);
        return "OK";
    }

    /**
     * 设置字符串值，支持NX、EX、PX等选项
     */
    public String set(String key, String value, String... options) {
        boolean nx = false;
        boolean xx = false;
        int exSeconds = -1;
        long pxMilliseconds = -1;
        
        // 解析选项
        for (int i = 0; i < options.length; i++) {
            String option = options[i].toUpperCase();
            switch (option) {
                case "NX":
                    nx = true;
                    break;
                case "XX":
                    xx = true;
                    break;
                case "EX":
                    if (i + 1 < options.length) {
                        try {
                            exSeconds = Integer.parseInt(options[++i]);
                        } catch (NumberFormatException e) {
                            return null; // 无效的过期时间
                        }
                    }
                    break;
                case "PX":
                    if (i + 1 < options.length) {
                        try {
                            pxMilliseconds = Long.parseLong(options[++i]);
                        } catch (NumberFormatException e) {
                            return null; // 无效的过期时间
                        }
                    }
                    break;
            }
        }
        
        // 检查NX/XX条件
        boolean exists = core.exists(key);
        if (nx && exists) {
            return null; // 键已存在，NX条件不满足
        }
        if (xx && !exists) {
            return null; // 键不存在，XX条件不满足
        }
        
        // 设置值
        core.put(key, value, RedisCore.DataType.STRING);
        
        // 设置过期时间
        if (exSeconds > 0) {
            core.expire(key, exSeconds);
        } else if (pxMilliseconds > 0) {
            core.expireAt(key, System.currentTimeMillis() + pxMilliseconds);
        }
        
        return "OK";
    }

    /**
     * 获取字符串值
     */
    public String get(String key) {
        Object value = core.get(key);
        if (value == null || !(value instanceof String)) {
            return null;
        }
        return (String) value;
    }

    /**
     * 自增操作
     */
    public Long incr(String key) {
        String value = get(key);
        long num = 0;
        if (value != null) {
            try {
                num = Long.parseLong(value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        num++;
        set(key, String.valueOf(num));
        return num;
    }

    /**
     * 自减操作
     */
    public Long decr(String key) {
        String value = get(key);
        long num = 0;
        if (value != null) {
            try {
                num = Long.parseLong(value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        num--;
        set(key, String.valueOf(num));
        return num;
    }

    /**
     * 批量设置字符串值
     */
    public String mset(String... keyValues) {
        if (keyValues.length % 2 != 0) {
            return null; // 参数数量必须是偶数
        }
        for (int i = 0; i < keyValues.length; i += 2) {
            set(keyValues[i], keyValues[i + 1]);
        }
        return "OK";
    }

    /**
     * 批量获取字符串值
     */
    public String[] mget(String... keys) {
        String[] values = new String[keys.length];
        for (int i = 0; i < keys.length; i++) {
            values[i] = get(keys[i]);
        }
        return values;
    }

    /**
     * 设置值，如果键不存在
     */
    public boolean setnx(String key, String value) {
        if (core.exists(key)) {
            return false;
        }
        set(key, value);
        return true;
    }

    /**
     * 设置带过期时间的值
     */
    public String setex(String key, int seconds, String value) {
        set(key, value);
        core.expire(key, seconds);
        return "OK";
    }
}